"""
Grave! Important! Важно!

Proletoj el ĉiuj landoj, unuiĝu!
Workers of the world, unite!
Пролетарии всех стран, соединяйтесь!

https://tkom.pro
"""

import sys
import re
from types import FunctionType
from django.urls import resolve # django 2
from django.utils.deprecation import MiddlewareMixin
from django.template.loader_tags import ExtendsNode
from django.template.response import TemplateResponse


class SiriusoAutomataKunteksto(MiddlewareMixin):
    def process_template_response(self, request, response):
        templates_list = response.template_name if type(response.template_name) == list else [response.template_name]
        templates_list.extend(self._template_parents(request, response))
        context = self._get_context(templates_list, request)

        if context:
            response.context_data.update(context)

        return response

    def _template_parents(self, request, response):
        parents = []
        nodelist = response.resolve_template(response.template_name).template.nodelist

        for node in nodelist:

            if isinstance(node, ExtendsNode):
                parents.append(node.parent_name.var)
                parent_response = TemplateResponse(request, node.parent_name.var, {})
                parents.extend(self._template_parents(request, parent_response))

        return parents

    def _get_view_kwargs(self, request):
        resolver = resolve(request.path)

        if hasattr(resolver, 'kwargs'):
            return resolver.kwargs

        return None

    def _get_context(self, templates_list, request):
        # Поиск модулей с функциями определения контекста
        # под определенный шаблон

        # Возвращаемый контекст
        context = {}

        # Шаблон имени функции определения контекста
        reg = re.compile('context_*')

        # Параметры, переданные представлению для отрисовки шаблона
        kwargs = self._get_view_kwargs(request)

        for template in templates_list:
            parted = template.split('/')
            apps = parted[0]
            template_name = parted[-1]
            template_name = template_name.split('.')[0]

            # Ищем модуль с функциями определения контекста
            try:
                cur_module = __import__('%s.templatecontexts.%s' % (apps, template_name), globals(), locals(), [])
                template_spec = getattr(getattr(cur_module, 'templatecontexts'), template_name)

                # Отфильтровываем атрибуты только по шаблону
                contexts_spec = list(filter(reg.match, dir(template_spec)))

                # Перебираем все отфильтрованные атрибуты
                for spec_name in contexts_spec:
                    spec = getattr(template_spec, spec_name)

                    # Если атрибут - функция
                    if type(spec) is FunctionType:
                        # выполняем его
                        context.update(spec(request, **kwargs))

            except ImportError: # ModuleNotFoundError:
                continue

        return context